home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_1199 / 1011 < prev    next >
Encoding:
Internet Message Format  |  1994-08-27  |  4.5 KB

  1. Date: Mon, 14 Feb 94 13:42:01 PST
  2. From: hyc@hanauma.jpl.nasa.gov (Howard Chu)
  3. Message-Id: <9402142142.AA07231@hanauma.jpl.nasa.gov>
  4. To: ersmith@netcom.com, mint@atari.archive.umich.edu
  5. Subject: Re:  user-written interrupt handlers
  6.  
  7. >Date: Mon, 14 Feb 1994 11:47:04 -0800
  8. >From: ersmith@netcom.com (Eric R. Smith)
  9. >
  10. >I would think that any user-supplied interrupt handlers should be provided
  11. >as device drivers; they can then call into the kernel via the table that
  12. >MiNT provides, and don't have to worry about going through trap #1.
  13.  
  14. Well, I decided I was taking an impossible tack, so I tried again from a
  15. different angle... Now I have a new DOS call Psiginter(vec,sig) which will
  16. install an interrupt handler for the user, that will send the calling process
  17. the signal sig when the given interrupt occurs. I basically copied the Do_sig
  18. code in intr.spp, pointing it to a routine that just does post_sig as
  19. specified. Unfortunately, this doesn't work reliably; I get all kinds of
  20. bizarre crashes. I don't suppose any of you could look it over and point out
  21. what I'm not catching...?
  22.  
  23. The particular application is to handle DMA sound interrupts, fyi...
  24.  
  25.  
  26. *** 1.1    1994/02/13 11:00:22
  27. --- intr.spp    1994/02/14 21:40:17
  28. ***************
  29. *** 225,228 ****
  30. --- 225,283 ----
  31.       
  32.   ;
  33. + ; Generic routine for handling any user-specified interrupts. On 68000, the
  34. + ; vector number is stored in the high byte of the program counter.
  35. + ;
  36. +     XDEF    _new_intr
  37. + _new_intr:
  38. + ;    ori.w    #$0700,sr
  39. +     subq.w    #2,sp        ; reserve space for fake frame word
  40. +     move.l    d0,-(sp)    ; save d0
  41. + %ifndef ONLY030
  42. +     tst.w    ($59e.w)    ; is frame format on stack?
  43. +     bne.s    nvec        ; yes, go use it
  44. +     bsr.s    ndummy        ; push PC to stack
  45. +     nop
  46. + ndummy:    
  47. +     move.l    (sp)+,d0    ; pop PC to d0
  48. +     swap    d0        ; move hi word to lo word
  49. +     lsr.w    #6,d0        ; move hi byte into vector offset position
  50. +     andi.b    #$fc,d0        ; clear any garbage from lo 2 bits
  51. +     bra.s    ngot        ; continue
  52. + nvec:
  53. + %endif
  54. +     move.w    12(sp),d0    ; get frame word
  55. +     andi.w    #$ffc,d0    ; mask down to vector offset
  56. + ngot:
  57. +     move.w    d0,4(sp)    ; store vector offset
  58. +     move.l    (sp)+,d0    ; restore d0
  59. +     tst.w    _in_kernel    ; did we interrupt the kernel?
  60. +     bne.s    kern_intr    ; yes ...
  61. +     move.l    _curproc,-(sp)
  62. +     addq.l    #4,(sp)        ; push offset of save area
  63. +     jsr    _build_context    
  64. +     move.w    4(sp),d0    ; pull vector offset from stack to d0
  65. +     move.l    _curproc,a4
  66. +     move.l    (a4),sp        ; get into system stack
  67. +     move.w    d0,-(sp)    ; save vector offset
  68. +     jsr    _enter_kernel    
  69. +     jsr    _sig_user    ; send signal
  70. +     ori.w    #$0700,sr        ; spl7()
  71. +     jsr    _leave_kernel        ; leave kernel
  72. +     addq.w    #4,a4            ; get context save area address
  73. +     move.l    a4,-(sp)        ; push it
  74. +     jsr    _restore_context    ; restore the context
  75. + kern_intr:
  76. +     movem.l    d0-d2/a0-a2,-(sp)    ; save regs
  77. +     move.w    24(sp),-(sp)        ; copy vector offset up
  78. +     jsr    _sig_user        ; send signal
  79. +     addq.w    #2,sp            ; pop copy of vector offset
  80. +     movem.l    (sp)+,d0-d2/a0-a2    ; restore regs
  81. +     addq.w    #2,sp            ; pop vector offset
  82. +     rte
  83. + ;
  84.   ; New bus error handler for memory protection: get the ssp and
  85.   ; put it in the proc structure before calling
  86. *** 1.1    1994/02/14 21:38:04
  87. --- dossig.c    1994/02/14 21:35:30
  88. ***************
  89. *** 211,212 ****
  90. --- 211,289 ----
  91.       return 0;
  92.   }
  93. + /*
  94. +  * p_sigintr: Set an exception vector to send us the specified signal.
  95. +  */
  96. + typedef struct usig {
  97. +     int vec;
  98. +     int sig;
  99. +     PROC *proc;
  100. +     struct usig *next;
  101. + } usig;
  102. + static usig *usiglst;
  103. + extern long mcpu;    
  104. + long ARGS_ON_STACK
  105. + p_siginter(vec, sig)
  106. +     int vec;
  107. +     int sig;
  108. + {
  109. +     extern void new_intr();
  110. +     long vec2;
  111. +     usig *new;
  112. +     if (!sig)        /* ignore signal 0 */
  113. +         return 0;
  114. +     vec2 = (long) new_intr;
  115. + #ifndef ONLY030
  116. +     if (mcpu == 0)
  117. +         vec2 |= vec << 24;
  118. + #endif
  119. +     new = kmalloc(sizeof(usig));
  120. +     new->vec = vec;
  121. +     new->sig = sig;
  122. +     new->proc = curproc;
  123. +     new->next = usiglst;
  124. +     usiglst = new;
  125. +     return setexc(vec, vec2);
  126. + }
  127. + /*
  128. +  * Find the process that requested this interrupt, and send it a signal.
  129. +  */
  130. + void ARGS_ON_STACK
  131. + sig_user(vec)
  132. +     int vec;
  133. + {
  134. +     usig *ptr;
  135. +     vec >>= 2;
  136. +     for (ptr = usiglst; ptr; ptr=ptr->next)
  137. +         if (vec == ptr->vec) {
  138. +             if (ptr->proc->wait_q != ZOMBIE_Q &&
  139. +                 ptr->proc->wait_q != TSR_Q) {
  140. +                 post_sig(ptr->proc, ptr->sig);
  141. +             }
  142. +             if (vec >= 64 && vec < 80) {
  143. +                 /*
  144. +                  * Clear in-service bit for ST MFP interrupts
  145. +                  */
  146. +                 char *mfp, c;
  147. +                 if (vec < 72)        /* Register B */
  148. +                     mfp = (char *)0xfffffa11L;
  149. +                 else            /* Register A */
  150. +                     mfp = (char *)0xfffffa0fL;
  151. +                 c = 1 << (vec & 7);
  152. +                 *mfp = ~c;
  153. +             }
  154. +                 
  155. +             break;
  156. +         }
  157. + }
  158.